/*
 * @Author: hx 2542123711@QQ.com
 * @Date: 2024-11-16 21:18:38
 * @LastEditors: hx 2542123711@QQ.com
 * @LastEditTime: 2024-11-17 21:50:32
 * @FilePath: /class_process-communication/Pipefile.cc
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#include<unistd.h>
#include<iostream>
 #include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include<string>
#include<cstring>
#include <sys/types.h>
#include <sys/wait.h>

#define MAX 1024
#define N 2
using namespace std;

//子进程去写
//1.子进程隔1s时间写一次，父进程不断的再读取数据
//读写端正常，管道为空，读端阻塞
// void WritePipe(int wfd)
// {
//     // char buff[MAX];
//     // buff[0] = 0;
//     string s = "I am child";
//     char buff[MAX];
//     buff[0]=0;
//     int fatherpid = getpid();
//     int number = 0;

//     while(true)
//     {
//         //先导进Buff数组，才能用wirte系统调用接口
//         snprintf(buff, sizeof(buff), "%s-%d-%d", s.c_str(), fatherpid, number++);
//         write(wfd, buff, strlen(buff));
//         sleep(1);
//     }
// }

// //父进程去读
// void ReadPipe(int rfd)
// {
//     char buff[MAX];
//     buff[0]=0;
//     int cnt = 0;
    
//     while(true)
//     {
//         ssize_t n = read(rfd, buff, sizeof(buff));
//         if(n > 0)
//         {
//             cout << "fatger get message[" << getpid() << "] " << buff << endl;
//             // sleep(5);
//         }
//         else if(n == 0)
//         {
//             cout << "read failed" << endl;
//         }
//         else
//         {
//             break;
//         }
       
//        cnt++;
//     }
// }

//2.子进程疯狂的取写，父进程每隔一段时间（1s）读一次，子进程会把管道写满，等待父进程去读取
//读写段正常，管道为满，写端阻塞
// void WritePipe(int wfd)
// {
//     // char buff[MAX];
//     // buff[0] = 0;
//     string s = "I am child";
//     char buff[MAX];
//     buff[0]=0;
//     int fatherpid = getpid();
//     int number = 0;

//     while(true)
//     {
//         //先导进Buff数组，才能用wirte系统调用接口
//         snprintf(buff, sizeof(buff), "%s-%d-%d", s.c_str(), fatherpid, number++);
//         write(wfd, buff, strlen(buff));
//     }
// }

// //父进程去读
// void ReadPipe(int rfd)
// {
//     char buff[MAX];
//     buff[0]=0;
//     int cnt = 0;
    
//     while(true)
//     {
//         sleep(5);
//         ssize_t n = read(rfd, buff, sizeof(buff));
//         if(n > 0)
//         {
//             cout << "fatger get message[" << getpid() << "] " << buff << endl;
//         }
//         else if(n == 0)
//         {
//             cout << "read failed" << endl;
//         }
//         else
//         {
//             break;
//         }
       
//        cnt++;
//     }
// }

//3.读端正常读，写端关闭,让读端读到空时结束读取
// void WritePipe(int wfd)
// {
//     // char buff[MAX];
//     // buff[0] = 0;
//     string s = "I am child";
//     char buff[MAX];
//     buff[0]=0;
//     int fatherpid = getpid();
//     int number = 0;

//     while(true)
//     {
//         //先导进Buff数组，才能用wirte系统调用接口
//         snprintf(buff, sizeof(buff), "%s-%d-%d ", s.c_str(), fatherpid, number++);
//         write(wfd, buff, strlen(buff));
//         if(number >= 5)
//         {
//             break;
//         }
//     }
// }

// void ReadPipe(int rfd)
// {
//     char buff[MAX];
//     buff[0]=0;
//     int cnt = 0;
    
//     while(true)
//     {
//         sleep(1);
//         ssize_t n = read(rfd, buff, sizeof(buff));
//         cout << "cnt: " << cnt << endl;

//         if(n > 0)
//         {
//             cout << "fatger get message[" << getpid() << "] " << buff << endl;
//         }
//         else if(n == 0)
//         {
//             cout << "read failed" << endl;
//             break;
//         }
//         else
//         {
//             break;
//         }
//     }
// }

//4.读端关闭，写端一直写入，操作系统会杀死写端进程
void WritePipe(int wfd)
{
    string s = "I am child";
    char buff[MAX];
    int fatherpid = getpid();
    int number = 0;

    while(true)
    {
        buff[0]=0;
        sleep(1);
        snprintf(buff, sizeof(buff), "%s-%d-%d ", s.c_str(), fatherpid, number++);
        write(wfd, buff, strlen(buff));
    }
}

void ReadPipe(int rfd)
{
    char buff[MAX];
    buff[0]=0;
    int cnt = 0;
    
    while(true)
    {
        ssize_t n = read(rfd, buff, sizeof(buff));
        // cout << "cnt: " << cnt << endl;

        if(n > 0)
        {
            buff[n] = 0;
            cout << "fatger get message[" << getpid() << "]#" << buff << endl;
        }
        else if(n == 0)
        {
            cout << "read failed" << endl;
            break;
        }
        else
        {
            break;
        }

        cnt++;
        if(cnt >= 3)
        {
            break;
        }
    }
}

int main()
{
    int pipefd[N] = {0};
    int n = pipe(pipefd);
    if(n < 0)
    {
        return 1;
    }

    pid_t id = fork();
    if(id < 0)
    {
        printf("fork failed\n");
        return 2;
    }
    //id == 0是子进程 id>0 是父进程
    else if(id == 0)
    {
        //child
        close(pipefd[0]);

        WritePipe(pipefd[1]);

        close(pipefd[1]);
        exit(0);
    }
   
    //father
    close(pipefd[1]);

    ReadPipe(pipefd[0]);//读取3s
    close(pipefd[0]);
    cout << "father closed fd: "<< pipefd[0] << endl;
    sleep(5);//为了观察僵尸进程

    // cout << "he" <<endl;
    int status = 0;
    pid_t rid = waitpid(id, &status, 0);
    if(rid < 0)
    {
        return 3;
    }
    cout << "wait success " << rid << " exit code:" << ((status>>8)&(0xff)) << " exit signal:" << (status&0x7f) << endl;
    
    sleep(5);
    cout << "father quit" << endl;
        
    return 0;
}
